package workload

import (
	//"errors"
	"fmt"
	k8sclient "k8s_gui_client/k8s/client"
	"os"
	"time"

	utils "k8s_gui_client/utils"

	"github.com/xuri/excelize/v2"
)

//pod list
func GetPods(namespace string) (map[string]interface{}, error) {

	if namespace != "" {
		return k8sclient.CurrentK8sApiClient.GetAPI("/api/v1/namespaces/" + namespace + "/pods")
	} else {
		return k8sclient.CurrentK8sApiClient.GetAPI("/api/v1/pods")

	}

}

func PodURL(namespace string, name string) string {
	return "/api/v1/namespaces/" + namespace + "/pods/" + name
}

func GetPodYaml(namespace string, name string) (string, error) {
	return k8sclient.CurrentK8sApiClient.GetAPIAsYaml(PodURL(namespace, name))
}

func PodLogURL(namespace string, name string, container string) string {
	return "/api/v1/namespaces/" +
		namespace +
		"/pods/" +
		name +
		"/log?container=" +
		container
}
func PodPreviousLogURL(namespace string, name string, container string) string {
	return "/api/v1/namespaces/" +
		namespace +
		"/pods/" +
		name +
		"/log?container=" +
		container +
		"&previous=true"
}

func GetPodLog(namespace string, name string, container string) (string, error) {
	return k8sclient.CurrentK8sApiClient.GetAPIAsText(PodLogURL(namespace, name, container))
}
func GetPodPreviousLog(namespace string, name string, container string) (string, error) {
	return k8sclient.CurrentK8sApiClient.GetAPIAsText(PodPreviousLogURL(namespace, name, container))
}

func OpenPodShell(namespace string, name string, container string) error {
	return utils.ExecRun(fmt.Sprintf("cmd.exe /k start kubectl exec -it -n %s %s %s -- sh ", namespace, name, container))
}

func ExportPodReports() error {

	pods, err := k8sclient.CurrentK8sApiClient.GetAPI("/api/v1/pods")
	if err != nil {
		return err
	}

	os.MkdirAll("d:/tmp", os.ModePerm)

	f := excelize.NewFile()
	f.SetSheetName("Sheet1", "pods")

	f.SetCellStr("pods", "A1", "name")
	f.SetCellStr("pods", "B1", "namespace")
	f.SetCellStr("pods", "C1", "containers")
	f.SetCellStr("pods", "D1", "restarts")
	f.SetCellStr("pods", "E1", "nodeName")

	f.SetCellStr("pods", "F1", "requests.cpu")
	f.SetCellStr("pods", "G1", "requests.memory(G)")
	f.SetCellStr("pods", "H1", "limits.cpu")
	f.SetCellStr("pods", "I1", "limits.memory(G)")
	f.SetCellStr("pods", "J1", "use.cpu")
	f.SetCellStr("pods", "K1", "use.memory(G)")

	items := pods["items"].([]interface{})

	podMetrics ,_ :=GetPodMetrics()

	for index, item := range items {
		pod := item.(map[string]interface{})

		metadata := pod["metadata"].(map[string]interface{})

		status := pod["status"].(map[string]interface{})

		spec := pod["spec"].(map[string]interface{})

		name := metadata["name"].(string)
		namespace := metadata["namespace"].(string)
		nodeName := spec["nodeName"].(string)
		use_cpu := 0.0
		use_memory := 0.0
		if podMetrics[namespace+"|"+name]!=nil {
		podMetric := podMetrics[namespace+"|"+name].(map[string]interface{})

		
        if podMetric["containers"]!=nil {
			containers := podMetric["containers"].([]interface{})
			if len(containers) > 0 {
				for _, _container := range containers {
					container := _container.(map[string]interface{})

					if container["usage"] !=nil {
						usage := container["usage"].(map[string]interface{})

						use_cpu = use_cpu + utils.To_cpu_h(usage["cpu"].(string))
						use_memory = use_memory + utils.To_memory_g(usage["memory"].(string))
					}
				}
			}
		}
	}

		f.SetCellStr("pods", fmt.Sprintf("A%d", index+2), name)
		f.SetCellStr("pods", fmt.Sprintf("B%d", index+2), namespace)
		if status["containerStatuses"] != nil {
			containerStatuses := status["containerStatuses"].([]interface{})
			f.SetCellInt("pods", fmt.Sprintf("C%d", index+2), len(containerStatuses))

			if len(containerStatuses) > 0 {
				containerStatus := containerStatuses[0].(map[string]interface{})

				if containerStatus["restartCount"] != nil {
					restartCount := containerStatus["restartCount"].(float64)
					f.SetCellFloat("pods", fmt.Sprintf("D%d", index+2), restartCount, 2, 32)
				}
			}
		}
		f.SetCellStr("pods", fmt.Sprintf("E%d", index+2), nodeName)

		if spec["containers"] != nil {
			requests_cpu := 0.0
			limits_cpu := 0.0
			requests_memory := 0.0
			limits_memory := 0.0
			containers := spec["containers"].([]interface{})

			if len(containers) > 0 {
				for _, _container := range containers {
					container := _container.(map[string]interface{})
					if container["resources"] != nil {
						resources := container["resources"].(map[string]interface{})

						if resources["requests"] != nil {
							requests := resources["requests"].(map[string]interface{})
							if requests["cpu"] != nil && requests["cpu"].(string) != "" {
								requests_cpu = requests_cpu + utils.To_cpu_h(requests["cpu"].(string))
							}
							if requests["memory"] != nil && requests["memory"].(string) != "" {
								requests_memory = requests_memory + utils.To_memory_g(requests["memory"].(string))
							}
						}
						if resources["limits"] != nil {
							limits := resources["limits"].(map[string]interface{})
							if limits["cpu"] != nil && limits["cpu"].(string) != "" {
								limits_cpu = limits_cpu + utils.To_cpu_h(limits["cpu"].(string))
							}
							if limits["memory"] != nil && limits["memory"].(string) != "" {
								limits_memory = limits_memory + utils.To_memory_g(limits["memory"].(string))
							}
						}
					}
				}

				f.SetCellFloat("pods", fmt.Sprintf("F%d", index+2), requests_cpu, 2, 32)
				f.SetCellFloat("pods", fmt.Sprintf("G%d", index+2), requests_memory, 2, 32)
				f.SetCellFloat("pods", fmt.Sprintf("H%d", index+2), limits_cpu, 2, 32)
				f.SetCellFloat("pods", fmt.Sprintf("I%d", index+2), limits_memory, 2, 32)
				f.SetCellFloat("pods", fmt.Sprintf("J%d", index+2), use_cpu, 2, 32)
				f.SetCellFloat("pods", fmt.Sprintf("K%d", index+2), use_memory, 2, 32)

			}
		}

	}

	filename := fmt.Sprintf("d:/tmp/pods-%s.xlsx", time.Now().Format("20060102150405000"))
	if err := f.SaveAs(filename); err != nil {
		return err
	}
	return utils.ExecRun(fmt.Sprintf("cmd.exe /k start %s ", filename))

}



//pod 监控指标
func GetPodMetrics() (map[string]interface{}, error) {

	Metrics, err := k8sclient.CurrentK8sApiClient.GetAPI("/apis/metrics.k8s.io/v1beta1/pods")
	if err != nil {
		return make(map[string]interface{}), err
	}

	items := Metrics["items"].([]interface{})

	if len(items) > 0 {
		result := make(map[string]interface{})
		for _, item := range items {
			itemMap := item.(map[string]interface{})
			metadata := itemMap["metadata"].(map[string]interface{})
			name := metadata["name"].(string)
			namespace := metadata["namespace"].(string)
			result[namespace+"|"+name] = itemMap
		}
		return result, nil
	}

	return make(map[string]interface{}), nil
}